/*
 *  Gregorian.h
 *  Calendar
 *
 *  Created by Fredrik Gustafsson on 9/30/10.
 *  Copyright 2010 Kungliga Tekniska Högskolan. All rights reserved.
 *
 */

#ifndef LAB2_Gregorian_H_
#define LAB2_Gregorian_H_

#include "date.h"
#include "kattistime.h"
#include <stdexcept>
#include <string>
#include <cmath>

namespace lab2 {
	class Gregorian : public Date {
	public:	
		explicit Gregorian();
		Gregorian(int,int,int);
		Gregorian(const Date*);
		Gregorian(const Date&);
		
		template <class D>
		Gregorian(const D* d) {
			this->set_date_from_base(d->mod_julian_day());
		}
		
		template <class D>
		Gregorian(const D& d) {
			this->set_date_from_base(d.mod_julian_day());
		}
		
		virtual const int year() const;
		virtual const int month() const;
		virtual const int day() const;
		virtual const int week_day() const; 
		virtual const int days_per_week() const;
		virtual const int days_this_month() const;
		virtual const int months_per_year() const;
		virtual const std::string week_day_name() const;
		virtual const std::string month_name() const;

		virtual Date& add_year(const int);
		virtual Date& add_month(const int);
		virtual Date& add_year();
		virtual Date& add_month();
		
		virtual void print(std::ostream&) const;
		
		const int mod_julian_day() const;
		
	protected:
		const bool assert_valid_date(int, int,int);
		
		virtual void set_date_from_base(int base);
		virtual const int days_of_month(int month, int year) const;
		virtual bool leap_year(int year) const;
		virtual const int get_century_offset(int year) const;
		virtual Date& sub_month();
		int curr_day;
		int curr_month;
		int curr_year;
		std::string months[13];
	};
}

#endif
